package com.ruoyi.system.service.impl;

import com.ruoyi.system.entity.*;
import com.ruoyi.system.service.IPveService;
import com.ruoyi.system.service.ISysConfigService;
import it.corsinvest.proxmoxve.api.PveClient;
import jakarta.annotation.Resource;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class PveServiceImpl implements IPveService {

    @Resource
    private ISysConfigService sysConfigService;


    @Override
    public SunPanelCPU getCpuState() throws Exception {
        SunPanelCPU sunPanelCPU = new SunPanelCPU();

        PveClient client = connect();
        if (client !=null) {
            JSONObject jsonObject = (JSONObject) client.getNodes().index().getResponse().getJSONArray("data").get(0);

            sunPanelCPU.setCpuNum(1);
            sunPanelCPU.setCoreCount(jsonObject.getInt("maxcpu"));
            sunPanelCPU.setModel("CPU");

            ArrayList<Double> doubles = new ArrayList<>();
            for (int i = 0; i < jsonObject.getInt("maxcpu"); i++) {
                doubles.add(jsonObject.getDouble("cpu") * 100);
            }
            sunPanelCPU.setUsages(doubles);

        }

        return sunPanelCPU;
    }

    @Override
    public SunPanelMemony getMemonyState() throws Exception {
        SunPanelMemony sunPanelMemony = new SunPanelMemony();

        PveClient client = connect();
        if (client !=null) {
            JSONObject jsonObject = (JSONObject) client.getNodes().index().getResponse().getJSONArray("data").get(0);

            sunPanelMemony.setFree(jsonObject.getLong("mem"));
            sunPanelMemony.setUsed(jsonObject.getLong("mem"));

            sunPanelMemony.setTotal(jsonObject.getLong("maxmem"));
            sunPanelMemony.setUsedPercent((double) jsonObject.getLong("mem") / jsonObject.getLong("maxmem") * 100);

        }

        return sunPanelMemony;
    }

    @Override
    public ArrayList<SunPanelDiskList> getDiskMountpoints() throws Exception {

        ArrayList<SunPanelDiskList> sunPanelDiskLists = new ArrayList<>();

        PveClient client = connect();
        if (client !=null) {
            JSONArray jsonArray = client.getStorage().index().getResponse().getJSONArray("data");
            for (Object o : jsonArray) {
                JSONObject a = (JSONObject) o;
                SunPanelDiskList e = new SunPanelDiskList();

                e.setMountpoint(a.getString("storage"));
                e.setDevice("proc");
                e.setFstype("proc");
                e.setOpts(new ArrayList<>());

                sunPanelDiskLists.add(e);
            }

        }

        return sunPanelDiskLists;
    }

    @Override
    public SunPanelDisk getDiskStateByPath(String path) throws Exception {

        SunPanelDisk sunPanelDisk = new SunPanelDisk();

        PveClient client = connect();
        if (client !=null) {
            PveClient.PVENodes.PVENodeItem.PVEStorage.PVEStorageItem pveStorageItem = client.getNodes().get("pve").getStorage().get(path);

            JSONObject data = (JSONObject) pveStorageItem.getStatus().readStatus().getResponse().get("data");

            sunPanelDisk.setFree(data.getLong("avail"));
            sunPanelDisk.setMountpoint(path);
            sunPanelDisk.setTotal(data.getLong("total"));
            sunPanelDisk.setUsed(data.getLong("used"));
            sunPanelDisk.setUsedPercent((double) data.getLong("used") /data.getLong("total")*100);

        }
        return sunPanelDisk;
    }


    @Override
    public SunPanelDockerList getLxcAndQemuList() throws Exception{

        JSONArray lxcs = (JSONArray) connect().getNodes().get("pve").getLxc().vmlist().getResponse().get("data");

        JSONArray vms = (JSONArray)  connect().getNodes().get("pve").getQemu().vmlist().getResponse().get("data");


        SunPanelDockerList sunPanelDockerList = new SunPanelDockerList();
        sunPanelDockerList.setCount(lxcs.length()+vms.length());
        ArrayList<SunPanelDockerListItem> list = new ArrayList<>();

        for (Object a : lxcs) {
            JSONObject lxc = (JSONObject) a;
            SunPanelDockerListItem e = new SunPanelDockerListItem();
            e.setPorts(new ArrayList<>());
            e.setName(lxc.getString("name"));
            e.setStatus(lxc.getString("status").equals("running")?"running":"exited");
            e.setState(lxc.getString("status").equals("running")?"running":"exited");
            e.setImage("lxc");
            e.setCreateTime("");
            e.setId("pve-lxc-"+lxc.getInt("vmid"));
            list.add(e);
        }

        for (Object a : vms) {
            JSONObject lxc = (JSONObject) a;
            SunPanelDockerListItem e = new SunPanelDockerListItem();
            e.setPorts(new ArrayList<>());
            e.setName(lxc.getString("name"));
            e.setStatus(lxc.getString("status").equals("running")?"running":"exited");
            e.setState(lxc.getString("status").equals("running")?"running":"exited");
            e.setImage("vm");
            e.setCreateTime("");
            e.setId("pve-vm-"+lxc.getInt("vmid"));
            list.add(e);
        }


        sunPanelDockerList.setList(list);
        return sunPanelDockerList;
    }

    @Override
    public HashMap<String, SunPanelDockerStatus> getLxcStats(List<String> ids) throws Exception {
        JSONArray lxcs = (JSONArray) connect().getNodes().get("pve").getLxc().vmlist().getResponse().get("data");
        HashMap<String, SunPanelDockerStatus> stringSunPanelDockerStatusHashMap = new HashMap<>();
        for (String id : ids) {
            for (Object lxc : lxcs) {
                JSONObject a = (JSONObject) lxc;
                if ((a.getInt("vmid")+"").equals(id)) {
                    SunPanelDockerStatus sunPanelDockerStatus = new SunPanelDockerStatus();

                    sunPanelDockerStatus.setRunStatus(a.getString("status"));
                    sunPanelDockerStatus.setShotTime(new Date());
                    sunPanelDockerStatus.setErrorMessage("");
                    sunPanelDockerStatus.setNetworkTX(0);
                    sunPanelDockerStatus.setNetworkRX(0);
                    sunPanelDockerStatus.setMemory(a.getDouble("mem")/1024/1024);
                    sunPanelDockerStatus.setCpuPercent(a.getDouble("cpu")*100);
                    sunPanelDockerStatus.setIoWrite(0);
                    sunPanelDockerStatus.setIoRead(0);
                    sunPanelDockerStatus.setCache(0);

                    stringSunPanelDockerStatusHashMap.put("pve-lxc-"+a.getInt("vmid"),sunPanelDockerStatus);
                }
            }
        }
        return stringSunPanelDockerStatusHashMap;
    }

    @Override
    public HashMap<String, SunPanelDockerStatus> getQemuStats(List<String> ids) throws Exception {
        JSONArray vms = (JSONArray)  connect().getNodes().get("pve").getQemu().vmlist().getResponse().get("data");
        HashMap<String, SunPanelDockerStatus> stringSunPanelDockerStatusHashMap = new HashMap<>();
        for (String id : ids) {
            for (Object lxc : vms) {
                JSONObject a = (JSONObject) lxc;
                if ((a.getInt("vmid")+"").equals(id)) {
                    SunPanelDockerStatus sunPanelDockerStatus = new SunPanelDockerStatus();
                    sunPanelDockerStatus.setRunStatus(a.getString("status"));
                    sunPanelDockerStatus.setShotTime(new Date());
                    sunPanelDockerStatus.setErrorMessage("");
                    sunPanelDockerStatus.setNetworkTX(0);
                    sunPanelDockerStatus.setNetworkRX(0);
                    sunPanelDockerStatus.setMemory(a.getDouble("mem")/1024/1024);
                    sunPanelDockerStatus.setCpuPercent(a.getDouble("cpu"));
                    sunPanelDockerStatus.setIoWrite(0);
                    sunPanelDockerStatus.setIoRead(0);
                    sunPanelDockerStatus.setCache(0);
                    stringSunPanelDockerStatusHashMap.put("pve-vm-"+a.getInt("vmid"),sunPanelDockerStatus);
                }
            }
        }
        return stringSunPanelDockerStatusHashMap;
    }

    @Override
    public void execLxcSwitchActionByContainerID(boolean action, String id) throws Exception {
        if (action) {
            connect().getNodes().get("pve").getLxc().get(id).getStatus().getStart().vmStart();
        }else {
            connect().getNodes().get("pve").getLxc().get(id).getStatus().getShutdown().vmShutdown();
        }
    }

    @Override
    public void execVmSwitchActionByContainerID(boolean action, String id) throws Exception {
        if (action) {
            connect().getNodes().get("pve").getQemu().get(id).getStatus().getStart().vmStart();
        }else {
            connect().getNodes().get("pve").getQemu().get(id).getStatus().getShutdown().vmShutdown();
        }
    }

    PveClient connect() throws Exception{
        String host = sysConfigService.selectConfigByKey("pve.host");
        String port = sysConfigService.selectConfigByKey("pve.port");
        String username = sysConfigService.selectConfigByKey("pve.username");
        String password = sysConfigService.selectConfigByKey("pve.password");
        String realm = sysConfigService.selectConfigByKey("pve.realm");

        PveClient client = new PveClient(host, Integer.parseInt(port));
       return client.login(username, password, realm)?client:null;
    }


    public void test(){

    }
}
